package com.zg.autoform.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zg.common.core.dao.autoform.DiyImportTemplateDao;
import com.zg.common.core.dao.autoform.DiyImportTemplate;
import com.zg.autoform.dto.ImportFieldConfig;
import com.zg.autoform.service.ImportTemplateService;
import com.zg.autoform.service.ImportFieldConfigService;
import com.zg.autoform.web.vo.ImportTemplateDetailVo;
import com.zg.autoform.web.req.DeleteImportTemplateReq;
import com.zg.autoform.web.req.ListImportTemplateReq;
import com.zg.autoform.web.req.SaveImportTemplateReq;
import com.zg.common.core.A;
import com.zg.common.core.R;
import com.zg.common.core.dao.autoform.DiyForm;
import com.zg.common.core.dao.autoform.DiyFormDao;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Comparator;
import java.util.List;

/**
 * 导入模板服务实现
 * @author zg
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class ImportTemplateServiceImpl implements ImportTemplateService {

    private final DiyImportTemplateDao templateDao;
    private final DiyFormDao formDao;
    private final ImportFieldConfigService fieldConfigService;

    @Override
    @Transactional(rollbackFor = Exception.class)
//    @CacheEvict(value = "importTemplate", key = "#req.id", condition = "#req.id != null")
    public R<DiyImportTemplate> saveTemplate(SaveImportTemplateReq req) {
        // 1. 验证表单是否存在
        DiyForm form = formDao.getById(req.getFormId());
        A.isInDatabase(form, "表单");

        // 2. 验证模板名称唯一性
        LambdaQueryWrapper<DiyImportTemplate> wrapper = new LambdaQueryWrapper<DiyImportTemplate>()
                .eq(DiyImportTemplate::getFormId, req.getFormId())
                .eq(DiyImportTemplate::getName, req.getName());

        if (req.getId() != null) {
            wrapper.ne(DiyImportTemplate::getId, req.getId());
        }

        boolean exists = templateDao.count(wrapper) > 0;
        if (exists) {
            return R.error("模板名称已存在");
        }

        // 3. 验证字段配置
        validateFieldsConfig(req.getFields());

        // 4. 保存模板
        DiyImportTemplate template;
        if (req.getId() != null) {
            // 更新
            template = templateDao.getById(req.getId());
            A.isInDatabase(template, "模板不存在");
            BeanUtil.copyProperties(req, template, "id", "createTime", "createBy");
        } else {
            // 新增
            template = new DiyImportTemplate();
            BeanUtil.copyProperties(req, template);
        }

        // 5. 保存模板
        templateDao.saveOrUpdate(template);

        // 6. 保存字段配置
        if (req.getFields() != null && !req.getFields().isEmpty()) {
            // 排序字段配置
            req.getFields().sort(Comparator.comparing(ImportFieldConfig::getSort, Comparator.nullsLast(Integer::compareTo)));
            fieldConfigService.saveFieldConfigs(template.getId(), req.getFields());
        }

        log.info("保存导入模板成功，模板ID: {}, 名称: {}", template.getId(), template.getName());
        return R.success(template);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
//    @CacheEvict(value = "importTemplate", allEntries = true)
    public R<?> deleteTemplate(DeleteImportTemplateReq req) {
        // 1. 删除字段配置
        for (Long templateId : req.getIds()) {
            fieldConfigService.deleteFieldConfigsByTemplateId(templateId);
        }

        // 2. 删除模板
        templateDao.removeBatchByIds(req.getIds());
        log.info("删除导入模板成功，模板ID: {}", req.getIds());
        return R.success();
    }

    @Override
    public R<IPage<DiyImportTemplate>> listTemplates(ListImportTemplateReq req) {
        Page<DiyImportTemplate> page = new Page<>(req.getPage(), req.getPageSize());

        LambdaQueryWrapper<DiyImportTemplate> wrapper = new LambdaQueryWrapper<DiyImportTemplate>()
                .eq(req.getFormId() != null, DiyImportTemplate::getFormId, req.getFormId())
                .like(StrUtil.isNotBlank(req.getName()), DiyImportTemplate::getName, req.getName())
                .eq(req.getEnabled() != null, DiyImportTemplate::getEnabled, req.getEnabled())
                .orderByDesc(DiyImportTemplate::getUpdateTime);

        IPage<DiyImportTemplate> result = templateDao.page(page, wrapper);
        return R.success(result);
    }

    @Override
//    @Cacheable(value = "importTemplate", key = "#templateId")
    public DiyImportTemplate getTemplateById(Long templateId) {
        return templateDao.getById(templateId);
    }

    /**
     * 获取模板的字段配置列表
     * @param templateId 模板ID
     * @return 字段配置列表
     */
    public List<ImportFieldConfig> getTemplateFieldConfigs(Long templateId) {
        return fieldConfigService.getFieldConfigDtosByTemplateId(templateId);
    }

    /**
     * 验证字段配置
     */
    private void validateFieldsConfig(List<ImportFieldConfig> fields) {
        A.isTrue(!fields.isEmpty(), "字段配置不能为空");

        for (ImportFieldConfig field : fields) {
            A.isTrue(StrUtil.isNotBlank(field.getFieldLabel()), "字段中文名不能为空");
            A.isTrue(StrUtil.isNotBlank(field.getFieldName()), "字段名不能为空");
            A.isTrue(StrUtil.isNotBlank(field.getFieldType()), "字段类型不能为空");
        }

        // 检查字段名唯一性
        long distinctCount = fields.stream()
                .map(ImportFieldConfig::getFieldName)
                .distinct()
                .count();
        A.isTrue(distinctCount == fields.size(), "字段名不能重复");
    }
}
